home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / fp / ifp_unix.lzh / ifp / interp / inimport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-23  |  6.8 KB  |  263 lines

  1.  
  2. /****** inimport.c ****************************************************/
  3. /**                                                                  **/
  4. /**                    University of Illinois                        **/
  5. /**                                                                  **/
  6. /**                Department of Computer Science                    **/
  7. /**                                                                  **/
  8. /**   Tool: IFP                         Version: 0.5                 **/
  9. /**                                                                  **/
  10. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  11. /**                                                                  **/
  12. /**   Revised by: Arch D. Robison       Date:  Oct 28, 1985          **/
  13. /**                                                                  **/
  14. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  15. /**                            Prof. W. J. Kubitz                    **/
  16. /**                                                                  **/
  17. /**                                                                  **/
  18. /**------------------------------------------------------------------**/
  19. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  20. /**                       All Rights Reserved.                       **/
  21. /**********************************************************************/
  22.  
  23.  
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include "struct.h"
  27. #include "node.h"
  28. #include "string.h"
  29. #include "inob.h"
  30.  
  31.  
  32. /*
  33.  * DoubleDot
  34.  *
  35.  * Append a ".." to path list by deleting last element.
  36.  *       
  37.  * Input
  38.  *      *F = file descriptor
  39.  *      *C = pointer to path list 
  40.  *
  41.  * Output
  42.  *      result = pointer to last null field, null if error.
  43.  */
  44. MetaPtr DoubleDot (F,C)           
  45.    InDesc *F;
  46.    register MetaPtr C;
  47.    {
  48.       register MetaPtr A;
  49.  
  50.       if (*C == NULL) {
  51.      (void) InError (F,"Too many ..'s.");
  52.      return NULL;
  53.       } else {        /* Remove last element from path list R */
  54.      do {
  55.         A = C;
  56.         C = &(*A)->Next;
  57.      } while (*C != NULL);
  58.      DelLPtr (*A);
  59.      *A = NULL;
  60.      return A;
  61.       }
  62.    }
  63.  
  64.  
  65. /*
  66.  * NodeDelim is the set of pathname delimiters.  Note that '>' and '<' are not
  67.  * in the set since they are (perversely) legal function names.  
  68.  */
  69. char NodeDelim[] = " ,[](){}|;:/\t\n";
  70.  
  71. /*
  72.  * InNode
  73.  *
  74.  * Input a path.  A path may represent a module, function, or functional
  75.  * variable.  Local functions are linked if possible to save time and space.
  76.  *
  77.  * The EBNF production definition for a node is:
  78.  *
  79.  *    ["/"] string { "/" (string | "..") }
  80.  *
  81.  * Input
  82.  *    *F = input descriptor pointing to path
  83.  *    Env = environment
  84.  *
  85.  * Output
  86.  *      InOut = node (path list or node format) or functional variable (string)
  87.  *    *F = input descriptor pointing to next token after path
  88.  *
  89.  * A SysError may occur, in which case InOut is unchanged.
  90.  */
  91. boolean InNode (F,InOut,Env)
  92.    InDesc *F;
  93.    ObjectPtr InOut;
  94.    ListPtr Env;
  95.    {
  96.       ListPtr R = NULL;        /* path list accumulator                       */
  97.       register MetaPtr A = &R; /* pointer to Next field at end of accumulator */
  98.       boolean FirstSlash;
  99.    
  100.       if (Debug & DebugParse) printf ("InNode: '%s'",F->InPtr); 
  101.       if (!(FirstSlash = *F->InPtr == '/')) {
  102.  
  103.      if (IsTok (F,"..")) {
  104.         if (F->InDefMod != NULL) R = MakePath (F->InDefMod);
  105.         if (NULL == (A = DoubleDot (F,&R))) goto Error;
  106.      } else {
  107.  
  108.         Object S;                       /* relative path */
  109.         if (Debug & DebugParse) printf ("InNode: relative path\n");
  110.         S.Tag = BOTTOM;
  111.         if (NULL == InString (F,&S,NodeDelim,0)) {
  112.            if (!SysError) (void) InError (F,"path expected");
  113.            goto Error;
  114.         }    
  115.         if (!IsTok (F,"/")) {
  116.                  register NodePtr N;
  117. #if XDEF
  118.            for (; Env!=NULL; Env=Env->Next) 
  119.           if (ObEqual (&Env->Val,&S)) {
  120.              RepObject (InOut,&Env->Val);     /* functional variable */
  121.              return 1;
  122.           }
  123. #endif /* XDEF */
  124.            N = FindNode (F->InDefMod,S.String);   /* local function */
  125.            if (N != NULL) {
  126.           if (N->NodeType == IMPORT) {
  127.  
  128.              /* Imported function - resolve alias */
  129.              RepObject (InOut,&N->NodeData.NodeImp.ImpDef);
  130.  
  131.           } else {         /* Local function already linked */
  132.      
  133.              RepTag (InOut,NODE);
  134.              InOut->Node = CopyNPtr (N);
  135.           }
  136.           RepTag (&S,BOTTOM);
  137.           return 1;
  138.            }
  139.         }
  140.         if (F->InDefMod != NULL) R = MakePath (F->InDefMod);
  141.         while (*A != NULL) A = &(*A)->Next;
  142.         NewList (A,1L);
  143.         (*A)->Val.Tag = STRING;
  144.         (*A)->Val.String = S.String;
  145.      }
  146.       }
  147.       while (IsTok (F,"/")) {
  148.      if (IsTok (F,".."))
  149.         if (NULL == (A = DoubleDot (F,&R))) return 0;
  150.         else continue;
  151.      else {
  152.         NewList (A,1L);
  153.         if (SysError) goto Error;
  154.         if (NULL == InString (F,&(*A)->Val,NodeDelim,0)) {
  155.            if (SysError) goto Error;
  156.            else if (*F->InPtr != '/' && FirstSlash) {
  157.           (void) DoubleDot (F,&R);
  158.           break;
  159.            } else {
  160.           (void) InError (F,"Invalid path name");
  161.           goto Error;
  162.            }
  163.         }
  164.         A = &(*A)->Next;
  165.      }
  166.      FirstSlash = 0;
  167.       }
  168.  
  169.       RepTag (InOut,LIST);
  170.       InOut->List = R;
  171.       return 1;
  172. Error:
  173.       DelLPtr (R);
  174.       return 0;
  175.    }
  176.  
  177. /*
  178.  * InImport
  179.  *
  180.  * Input from an import file.
  181.  *
  182.  * An import file has the following format:
  183.  *
  184.  *      { 'FROM' path 'IMPORT' string {,string} ';' }
  185.  *
  186.  * Input
  187.  *      F = input
  188.  *      M = pointer to module node
  189.  */
  190. void InImport (F,M)
  191.    register InDesc *F;
  192.    register NodePtr M;
  193.    {
  194.       Object Path,Def;
  195.       register NodePtr N;
  196.       MetaPtr A;
  197.  
  198.       F->InFunName = NULL;
  199.       Path.Tag = BOTTOM;
  200.       Def.Tag = BOTTOM;
  201.  
  202.       while (!EndOfFile (F)) {
  203.  
  204.      if (!IsTok (F,"FROM")) {
  205.         (void) InError (F,"FROM expected");
  206.         break;
  207.      }
  208.  
  209.      (void) InNode (F,&Path,NIL); 
  210.      if (!IsTok (F,"IMPORT")) {
  211.         (void) InError (F,"IMPORT expected");
  212.         break;
  213.      }
  214.  
  215.      while (1) {
  216.  
  217.         if (NULL == InString (F,&Def," ,;\n",0)) {
  218.            if (!SysError) (void) InError (F,"function name expected");
  219.            goto Return;
  220.         }
  221.  
  222.         N = MakeChild (M,Def.String);
  223.  
  224.         switch (N->NodeType) {
  225.  
  226.            case IMPORT:
  227.           (void) InError (F,"duplicate imported identifier");
  228.           break;
  229.  
  230.            case DEF:
  231.           if (N->NRef > 1) {
  232.              (void) InError (F,"identifies function elsewhere");
  233.              break;
  234.           } /* else continue on down to NEWNODE */
  235.  
  236.            case NEWNODE: {
  237.           extern MetaPtr MakeCopy ();
  238.           N->NodeType = IMPORT;
  239.           N->NodeData.NodeImp.ImpDef.Tag = LIST;
  240.           A = MakeCopy (&N->NodeData.NodeImp.ImpDef.List, Path.List);
  241.           NewList (A,1L);
  242.           RepObject (&(*A)->Val,&Def);
  243.           break;
  244.            }
  245.         }
  246.         
  247.         if (IsTok (F,";")) break;
  248.         if (!IsTok (F,",")) {
  249.            (void) InError (F,"comma or semicolon expected");
  250.            goto Return;
  251.         }
  252.      }
  253.       }
  254. Return:
  255.       RepTag (&Path,BOTTOM);
  256.       RepTag (&Def,BOTTOM);
  257.       return;
  258.    }
  259.  
  260.  
  261. /******************************* inimport.c *******************************/
  262.  
  263.